package com.kalvan.client.model;

import com.kalvan.client.constant.CommonReturnCode;
import com.kalvan.client.exception.BizException;
import com.kalvan.client.exception.ReturnCode;
import com.kalvan.sensitive.utils.SensitiveInfoUtils;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;

/**
 * 统一返回对象
 *
 * @param <D> 表示data域对象
 * @author kalvan
 */
@Getter
@Setter
@Slf4j
public class WebResponse<D> extends HashMap<String, Object> {
    private static final long serialVersionUID = 1L;

    /**
     * 返回码
     */
    private static final String FIELD_CODE = "code" ;
    /**
     * 返回说明
     */
    private static final String FIELD_MSG = "msg" ;
    /**
     * 数据，分页时必须
     */
    private static final String FIELD_DATA = "data" ;
    /**
     * 数据,分页时必须
     */
    private static final String FIELD_COUNT = "count" ;


    /**
     * 返回
     *
     * @param code 返回码
     * @param msg  返回描述
     */
    private WebResponse(String code, String msg) {
        super.put(FIELD_CODE, code);
        super.put(FIELD_MSG, msg);
    }

    /**
     * @param code 返回码
     * @param desc 返回描述
     * @return 返回结果对象
     */
    public static WebResponse buildResult(String code, String desc) {
        return new WebResponse(code, desc);
    }

    /**
     * @param response Response
     * @return 返回结果对象
     */
    public static WebResponse buildResult(Response response) {
        return buildResult(response.getCode(), response.getDesc());
    }

    /**
     * 根据返回码解析返回对象
     *
     * @param returnCode 返回码对象
     * @return 返回结果对象
     */
    public static WebResponse buildResult(ReturnCode returnCode) {
        return buildResult(returnCode.getCode(), returnCode.getDesc());
    }

    /**
     * 根据biz异常解析返回对象
     *
     * @param exception bizException
     * @return 返回结果对象
     */
    public static WebResponse buildResult(BizException exception) {
        return buildResult(exception.getCode(), exception.getDesc());
    }

    /**
     * 返回处理成功结果
     *
     * @return 返回结果对象
     */
    public static WebResponse buildSuccess() {
        return buildResult(CommonReturnCode.SUCCESS);
    }

    /**
     * 返回处理成功结果
     *
     * @param msg 成功提示语
     * @return R
     */
    public static WebResponse buildSuccess(String msg) {
        return buildResult(CommonReturnCode.SUCCESS.getCode(), msg);
    }

    /**
     * 失败返回 code=1
     *
     * @param msg msg
     * @return R
     */
    public static WebResponse buildFail(String msg) {
        msg = StringUtils.isBlank(msg) ? "操作失败" : msg;
        return buildResult(CommonReturnCode.FAIL.getCode(), msg);
    }

    /**
     * 是否返回成功业务码,默认使用0000
     *
     * @return true /false
     */
    public boolean success() {
        return CommonReturnCode.SUCCESS.getCode().equals(this.get(FIELD_CODE));
    }

    /**
     * 设置返回数据data域-分页数据
     *
     * @param page page
     * @return R
     */
    public WebResponse<D> putPage(List page) {
        try {
            SensitiveInfoUtils.processObject(page);
        } catch (Exception e) {
            log.error("脱敏转换异常", e);
            return buildFail("返回数据转换异常");
        }
        super.put(FIELD_DATA, page);
        try {
            //通过反射获取总条数
            Field field = page.getClass().getDeclaredField("total");
            field.setAccessible(true);
            super.put(FIELD_COUNT, field.get(page));
        } catch (Exception e) {
            log.error("获取数据总条数异常", e);
        }
        return this;
    }

    /**
     * 设置返回数据data域,统一进行脱敏
     *
     * @param data data
     * @return R
     */
    public WebResponse<D> putData(Object data) {
        try {
            SensitiveInfoUtils.processObject(data);
        } catch (Exception e) {
            log.error("脱敏转换异常", e);
            return buildFail("返回数据转换异常");
        }
        super.put(FIELD_DATA, data);
        return this;
    }

    /**
     * 设置返回任意数据
     * 不建议使用,特殊情况下扩展使用
     *
     * @param key   key
     * @param value value
     * @return R
     */
    @Override
    public WebResponse put(String key, Object value) {
        try {
            SensitiveInfoUtils.processObject(value);
        } catch (Exception e) {
            log.error("脱敏转换异常", e);
            return buildFail("返回数据转换异常");
        }
        super.put(key, value);
        return this;
    }
//    /**
//     * http 拦截器异常返回
//     *
//     * @param response response
//     * @param r        r
//     */
//    public static void writerResponse(HttpServletResponse response, WebResponse r) {
//        response.setCharacterEncoding("UTF-8");
//        response.setContentType("text/html; charset=utf-8");
//        try (PrintWriter writer = response.getWriter()) {
//            writer.print(JSONObject.toJSONString(r));
//        } catch (IOException exception) {
//            log.error("响应异常", exception);
//        }
//    }
}
